﻿using System;
using System.Text.RegularExpressions;

namespace Nextensions.Net
{
    public static class URL
    {
        private static Regex _reAbsolute    = new Regex(@"^https?://", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        private static Regex _reCd          = new Regex(@"^\.\.(/|\\)", RegexOptions.Compiled);
        private static Regex _reLastDir     = new Regex(@"[^/]+/$", RegexOptions.Compiled);
        private static Regex _reNonDirResource        = new Regex(@"(?<=/)[^/]+$", RegexOptions.Compiled);

        public static string Combine(params string[] Url)
        {
            for (int i = 0; i < Url.Length; i++)
            {
                if (i > 0)
                {
                    while (Regex.IsMatch(Url[i], @"^\.\./"))
                    {
                        Url[i - 1] = Regex.Replace(Url[i - 1], @"[^/]+/[^/]*$", "");
                        Url[i] = Regex.Replace(Url[i], @"^\.\./", "");
                    }
                }
            }

            string result = Regex.Replace(String.Join("/", Url), @"(?<!^[a-z]+:)/{2,}", "/", RegexOptions.IgnoreCase);
            return result;
        }

        public static string GetBase(string URL)
        {
            return Regex.Match(URL, @"^(https?://)?[^/]+", RegexOptions.IgnoreCase).Value;
        }

        public static string GetDir(string URL)
        {
            return Regex.Match(URL, @"^(?<path>.+/)[^/]*$").Groups["path"].Value;
        }

        public static bool IsAbsolute(string URL)
        {
            return _reAbsolute.IsMatch(URL);
        }

        public static string MakeAbsolute(string BaseUrl, string RelativeUrl)
        {
            BaseUrl = _reNonDirResource.Replace(BaseUrl, "");

            while (_reCd.IsMatch(RelativeUrl))
            {
                RelativeUrl = _reCd.Replace(RelativeUrl, "");
                BaseUrl = _reLastDir.Replace(BaseUrl, "");
            }

            return URL.Combine(BaseUrl, RelativeUrl);
        }

        public static string SetRelative(string URL, string RelativePath)
        {
            if (Regex.IsMatch(RelativePath, @"^/"))
                return Combine(GetBase(URL), RelativePath);
            else
                return Combine(GetDir(URL), RelativePath);
        }
    }
}
